APP_TARGET        ?= app_demo.out
ARCH              ?= arm
MAKE_PARAM        :=
CURRENT_PATH      := $(shell pwd)

#=====================================================
# 
GIT_SHA = $(shell git rev-parse --short HEAD | awk 'NR==1')
GIT_SEQ = $(shell git rev-list HEAD | wc -l)
GIT_VER_INFO = $(GIT_SHA)-$(GIT_SEQ)
# GIT_SVR_PATH = $(shell git remote -v | awk 'NR==1' | sed 's/[()]//g' | sed 's/\t/ /g' |cut -d " " -f2)

ifneq ($(GIT_VER_INFO),)
  APP_CFLAGS += -DGIT_VERSION=\"$(GIT_VER_INFO)\"
else
  APP_CFLAGS += -DGIT_VERSION=\"unknown\"
endif

ifneq ($(GIT_SVR_PATH),)
  APP_CFLAGS += -DGIT_PATH=\"$(GIT_SVR_PATH)\"
else
  APP_CFLAGS += -DGIT_PATH=\"unknown\"
endif

ifeq ("$(origin V)", "command line")
  KBUILD_VERBOSE = $(V)
endif
ifndef KBUILD_VERBOSE
  KBUILD_VERBOSE = 0
endif

ifeq ($(KBUILD_VERBOSE),1)
  quiet =
  Q =
else
  quiet=quiet_
  Q = @
endif
ROOT_PERMISSION   ?= sudo
#=====================================================
# 源文件目录、头文件目录、obj文件目录
OBJ_DIR           := ./

INCDIRS 		  := ./ \
					 ./include

SRCDIRS			  := ./

STATIC_LIB_DIRS   := ./

STATIC_LIB_NAME   :=

# 这个只是用来显示对应的链接库的位置，方便链接出错时排查问题
STATIC_ALIB_NAME  :=

COMPILE_OPT_HEADER    := $(patsubst %, -I%, $(INCDIRS))
COMPILE_OPT_ALIB_PATH := $(patsubst %, -L%, $(STATIC_LIB_DIRS))
COMPILE_OPT_ALIB      := $(patsubst %, -l%, $(STATIC_LIB_NAME))

C_FILES			      := $(foreach dir, $(SRCDIRS), $(wildcard $(dir)/*.c))
C_FILES_NDIR		  := $(notdir  $(C_FILES))

COBJS			      := $(patsubst %, $(OBJ_DIR)%, $(C_FILES_NDIR:.c=.o))
OBJS			      := $(COBJS)
VPATH			      := $(SRCDIRS)
#=====================================================
# NFS 共享目录
TFTP_SERVER       ?= ~/3tftp
NFS_SERVER        ?= ~/4nfs

TFTP_DIR          ?= $(TFTP_SERVER)
ROOTFS_ROOT_DIR   ?= $(NFS_SERVER)/imx6ull_rootfs
#ROOTFS_MODULE_DIR ?= $(ROOTFS_ROOT_DIR)/lib/modules/4.19.71-00007-g51f3cd8ec-dirty
ROOTFS_MODULE_DIR ?= $(ROOTFS_ROOT_DIR)/drivers_demo

#=====================================================
# 编译工具和编译选项
# 相当于逻辑与(&&) ARCH=arm && CROSS_COMPILE_PREFIX= 时成立
# 当ARCH=arm的时候先判断 CROSS_COMPILE_PREFIX 是否为空，这个主要是因为作为子makefile的时候，
# 上层若是没赋值就导出，会导致这个值为空，非空的时候使用上层传入的值
ifeq ($(ARCH)_$(CROSS_COMPILE_PREFIX), arm_)
CROSS_COMPILE_PREFIX := arm-linux-gnueabihf-
endif

CC                   := $(CROSS_COMPILE_PREFIX)gcc
LD                   := $(CROSS_COMPILE_PREFIX)ld
OBJCOPY 		     := $(CROSS_COMPILE_PREFIX)objcopy
OBJDUMP 		     := $(CROSS_COMPILE_PREFIX)objdump

CFLAGS 		         := $(APP_CFLAGS) -g -Wall

# 编译模块和测试程序
all: $(APP_TARGET)

# GCC在链接时对依赖库的顺序是敏感的，被依赖的目标文件和库必须放在后面，代码升级后，链接顺序可能会变化。
$(APP_TARGET): $(OBJS)
	$(CC) $(CFLAGS) -o $@ $(OBJS) $(COMPILE_OPT_ALIB_PATH) $(COMPILE_OPT_ALIB)

$(COBJS) : $(OBJ_DIR)%.o : %.c
	$(CC) $(CFLAGS) -c $(COMPILE_OPT_HEADER) $< -o $@

# 拷贝相关文件到nfs共享目录
install:
	$(Q)$(ROOT_PERMISSION) cp -vf $(APP_TARGET) $(ROOTFS_MODULE_DIR)

uninstall:
	$(Q)$(ROOT_PERMISSION) rm -vf $(ROOTFS_MODULE_DIR)/$(APP_TARGET)

#=====================================================
# 清理工程和调试
PHONY += FORCE
FORCE:

PHONY += clean
clean: clean_app

clean_app:
	$(Q)rm -rf $(APP_TARGET) $(COBJS)

.PHONY: $(PHONY)

help:
	
print:
	$(Q)echo "TFTP_SERVER           : $(TFTP_SERVER)"
	$(Q)echo "NFS_SERVER            : $(NFS_SERVER)"
	$(Q)echo "ROOTFS_MODULE_DIR     : $(ROOTFS_MODULE_DIR)"
	$(Q)echo "ARCH                  : $(ARCH)"
	$(Q)echo "CC                    : $(CC)"
	$(Q)echo "CFLAGS                : $(CFLAGS)"
	$(Q)echo "COMPILE_OPT_HEADER    : $(COMPILE_OPT_HEADER)"
	$(Q)echo "COMPILE_OPT_ALIB_PATH : $(COMPILE_OPT_ALIB_PATH)"
	$(Q)echo "COMPILE_OPT_ALIB      : $(COMPILE_OPT_ALIB)"
	$(Q)echo "STATIC_ALIB_NAME      : $(STATIC_ALIB_NAME)"

#=====================================================
# 一些简单的注释笔记
# 符号	                   含义	                                         变量类型
#  =	递归赋值，当变量展开时，优先从后面展开	                            延时变量
# :=	该变量立即赋值（会覆盖前面的值），当变量展开时，优先从前面展开	       立即变量
# ?=	若前面没有定义该变量，则此处赋值，如果前面已经定义了，则此处不再赋值	延时变量
# +=	追加赋值	                                                     立即变量
#
# $<	第一个依赖文件的名称
# $@	目标文件的完整名称
# $^	所有不重复的目标依赖文件，以空格分开
# $?	所有时间戳比目标文件晚的的依赖文件，并以空格分开
